<script setup>
import { onMounted } from 'vue'
import * as THREE from 'three'
import { OrbitControls } from 'three/addons/controls/OrbitControls.js'

// 容器
let container
// 场景
let scene
// 宽度
let width
// 高度
let height
// 深度
let depth = 1400
// 图片
const IMAGE_SKY = new URL('../assets/sky.png', import.meta.url).href
const IMAGE_LOGO = new URL('../assets/logo.png', import.meta.url).href
// 相机在 z 轴上的位置
let zAxis
// 相机
let camera
// 渲染器
let renderer
// 球体
let sphere

onMounted(() => {
  container = document.getElementById('login-container')
  width = container.clientWidth
  height = container.clientHeight
  initScene()
  initSceneBg()
  initCamera()
  initRenderer()
  initOrbitControls()
  initSphere()
  initLight()
  animate()
})

// 初始化场景
const initScene = () => {
  scene = new THREE.Scene()
  scene.fog = new THREE.Fog(0x000000, 1, 10000)
}
// 初始化背景
const initSceneBg = () => {
  new THREE.TextureLoader().load(IMAGE_SKY, (texture) => {
    // 立方体
    const geometry = new THREE.BoxGeometry(width, height, depth)
    // 材质
    const material = new THREE.MeshBasicMaterial({ map: texture, side: THREE.BackSide })
    // 网格
    const mesh = new THREE.Mesh(geometry, material)
    // 添加到场景
    scene.add(mesh)
  })
}
// 初始化相机
const initCamera = () => {
  //视野夹角
  const fov = 15
  // 计算相机距离物体的距离
  const distance = width / 2 / Math.tan(15)
  // 计算相机在 z 轴上的位置
  zAxis = Math.floor(distance - depth / 2)
  // 创建相机
  camera = new THREE.PerspectiveCamera(fov, width / height, 1, 30000)
  // 设置相机位置 
  camera.position.set(0, 0, zAxis)
  // 相机看向原点
  camera.lookAt(0, 0, 0)
}
// 初始化渲染器
const initRenderer = () => {
  // 渲染器
  renderer = new THREE.WebGL1Renderer()
  // 设置尺寸
  renderer.setSize(width, height)
  // 添加DOM元素
  container.appendChild(renderer.domElement)
}
// 初始化轨道控制器
const initOrbitControls = () => {
  const controls = new OrbitControls(camera, renderer.domElement)
  controls.enabled = true
  controls.update()
}
// 初始化球体
const initSphere = () => {
  // 球体
  const geometry = new THREE.SphereGeometry(50, 64, 32)
  // 材质
  const material = new THREE.MeshPhongMaterial()
  // 纹理
  material.map = new THREE.TextureLoader().load(IMAGE_LOGO)
  // 网格
  sphere = new THREE.Mesh(geometry, material)
  sphere.position.set(-400, 200, -200)
  // 添加至场景
  scene.add(sphere)
}
// 初始化光源
const initLight = () => {
  // 环境光
  const ambientLight = new THREE.AmbientLight(0xffffff, 1)
  scene.add(ambientLight)
  // 点光源
  const pointLight = new THREE.PointLight(0x0655fd, 5, 0)
  pointLight.position.set(0, 100, -200)
  scene.add(pointLight)
}
// 球体自传
const sphereRotate = () => {
  sphere.rotateY(0.005)
}
// 动画刷新
const animate = () => {
  requestAnimationFrame(animate)
  sphereRotate()
  renderer.render(scene, camera)
}
</script>

<template>
  <div id="login-container"></div>
</template>

<style lang="less">
#login-container {
  width: 100%;
  height: 100vh;
}
</style>